package com.atguigu.gmall.cart.service;

import com.alibaba.fastjson.JSON;
import com.atguigu.gmall.cart.feign.GmallPmsClient;
import com.atguigu.gmall.cart.feign.GmallSmsClient;
import com.atguigu.gmall.cart.feign.GmallWmsClient;
import com.atguigu.gmall.cart.interceptor.CartInterceptor;
import com.atguigu.gmall.cart.mapper.CartMapper;
import com.atguigu.gmall.cart.pojo.Cart;
import com.atguigu.gmall.common.bean.UserInfo;
import com.atguigu.gmall.common.bean.ResponseVo;
import com.atguigu.gmall.pms.entity.SkuAttrValueEntity;
import com.atguigu.gmall.pms.entity.SkuEntity;
import com.atguigu.gmall.sms.vo.ItemSaleVo;
import com.atguigu.gmall.wms.entity.WareSkuEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class CartService{

    private static final String KEY_PREFIX = "cart:info:";
    private static final String PRICE_PREFIX = "cart:prcice:";
    @Autowired
    StringRedisTemplate redisTemplate;
    @Autowired
    GmallPmsClient pmsClient;
    @Autowired
    GmallSmsClient smsClient;
    @Autowired
    GmallWmsClient wmsClient;
    @Autowired
    CartMapper cartMapper;
    @Autowired
    CartServiceAsync cartServiceAsync;

    public void addCart(Cart cart) {
        String userId = getUserId();
        String key = KEY_PREFIX+userId;
        //获取购物车中的数据
        BigDecimal count = cart.getCount();
        BoundHashOperations<String, Object, Object> boundHashOps = redisTemplate.boundHashOps(key);
        if (!boundHashOps.hasKey(cart.getSkuId().toString())){
            //添加购物车
            // 1.查询sku商品信息
            cart.setUserId(userId);
            ResponseVo<SkuEntity> skuEntityResponseVo = pmsClient.querySkuById(cart.getSkuId());
            SkuEntity skuEntity = skuEntityResponseVo.getData();
            cart.setCheck(true);
            if (skuEntity!=null){
                cart.setDefaultImage(skuEntity.getDefaultImage());
                cart.setPrice(skuEntity.getPrice());
                cart.setTitle(skuEntity.getTitle());
            }
            // 2.查询商品的营销信息
            ResponseVo<List<ItemSaleVo>> listResponseVo = smsClient.queryItemSaleBySkuId(cart.getSkuId());
            List<ItemSaleVo> itemSaleVos = listResponseVo.getData();
            if (!CollectionUtils.isEmpty(itemSaleVos)){
                cart.setSales(JSON.toJSONString(itemSaleVos));
            }
            // 3.查询商品的销售属性
            ResponseVo<List<SkuAttrValueEntity>> listResponseVo1 = pmsClient.querySaleAttrValuesBySkuId(cart.getSkuId());
            List<SkuAttrValueEntity> skuAttrValueEntities = listResponseVo1.getData();
            if (!CollectionUtils.isEmpty(skuAttrValueEntities)){
                cart.setSaleAttrs(JSON.toJSONString(skuAttrValueEntities));
            }
            // 4.查询商品是否有库存
            ResponseVo<List<WareSkuEntity>> listResponseVo2 = wmsClient.queryWareSkusBySkuId(cart.getSkuId());
            List<WareSkuEntity> wareSkuEntities = listResponseVo2.getData();
            if (!CollectionUtils.isEmpty(wareSkuEntities)){
                cart.setStore(wareSkuEntities.stream().anyMatch(item->item.getStock()-item.getStockLocked()>0));
            }
            // 5.添加购物车商品到数据库中
            cartServiceAsync.insertByUserId(cart);
            // 6.添加商品单价到redis缓存中
            redisTemplate.opsForValue().set(PRICE_PREFIX+cart.getSkuId().toString(),cart.getPrice().toString());
        }else {
            //获取redis中的商品信息
            Object json = boundHashOps.get(cart.getSkuId().toString());
            cart = JSON.parseObject(json.toString(), Cart.class);
            //修改购物车中的数量
            cart.setCount(cart.getCount().add(count));
            //更新数据库中的购物车数据
            cartServiceAsync.updateCountBySkuIdAndUserId(userId,cart.getSkuId(),cart);
        }
        boundHashOps.put(cart.getSkuId().toString(),JSON.toJSONString(cart));
    }

    private String getUserId() {
        //获用户登录信息
        UserInfo userInfo = CartInterceptor.getUserInfo();
        Long userId = userInfo.getUserId();
        if (userId==null){
            //临时购物车
            return userInfo.getUserKey();
        }
        //用户购物车
        return userId.toString();
    }

    public Cart queryAddCart(Cart cart) {
        //获取用户登录信息
        String userId = getUserId();
        String key = KEY_PREFIX+userId;
        //获取redis中的商品信息
        BoundHashOperations<String, Object, Object> boundHashOps = redisTemplate.boundHashOps(key);
        String json = boundHashOps.get(cart.getSkuId().toString()).toString();
        return JSON.parseObject(json,Cart.class);
    }

    /*
    查询购物车
     */
    public List<Cart> queryCart() {
        // 1.获取临时用户
        UserInfo userInfo = CartInterceptor.getUserInfo();
        String userKey = userInfo.getUserKey();
        BoundHashOperations<String, Object, Object> boundHashOps = redisTemplate.boundHashOps(KEY_PREFIX + userKey);
        List<Object> values = boundHashOps.values();
        // 2.获取临时购物车数据
        List<Cart> cartList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(values)){
            //获取所有数据
            cartList = values.stream().map(item -> {
                Cart cart = JSON.parseObject(item.toString(), Cart.class);
                cart.setCurrentPrice(new BigDecimal(redisTemplate.opsForValue().get(PRICE_PREFIX+cart.getSkuId().toString())));
                return cart;
            }).collect(Collectors.toList());
        }
        // 3.获取登录用户信息 判读是否有用户登录
        Long userId = userInfo.getUserId();
        if (userId==null){
            return cartList;
        }
        // 4.获取登录用户的购物车 合并临时购物车
        BoundHashOperations<String, Object, Object> loginHashOps = redisTemplate.boundHashOps(KEY_PREFIX + userId);

        // 4.1遍历临时购物车数据
        if (!CollectionUtils.isEmpty(cartList)){
            cartList.forEach(cart -> {
                BigDecimal count = cart.getCount();
                //根据临时购物车的skuId查询登录购物车是否存在该商品
                if(loginHashOps.hasKey(cart.getSkuId().toString())){
                    //更新购物车数量
                    Object json = loginHashOps.get(cart.getSkuId().toString());
                    if (json!=null){
                        cart = JSON.parseObject(json.toString(), Cart.class);
                        cart.setCount(cart.getCount().add(count));
                        // TODO 更新mysql中的购物车商品数量
                        cartServiceAsync.updateCountBySkuIdAndUserId(userInfo.getUserId().toString(),cart.getSkuId(),cart);
                    }
                }else {
                    //添加购物车
                    // 1.重新设置sku的userid
                    cart.setUserId(userInfo.getUserId().toString());
                    // TODO 插入到数据库中
                    cartServiceAsync.insertByUserId(cart);
                }
                //更新redis中的购物车信息
                loginHashOps.put(cart.getSkuId().toString(),JSON.toJSONString(cart));
            });
        }
        // 5.删除临时购物车中的数据 mysql和redis
        redisTemplate.delete(KEY_PREFIX+userInfo.getUserKey());
        cartServiceAsync.delete(userInfo.getUserKey());
        // 6.查询用户购物车商品信息
        List<Object> loginList = loginHashOps.values();
        if (!CollectionUtils.isEmpty(loginList)){
            List<Cart> carts = loginList.stream().map(item -> {
                Cart cart = JSON.parseObject(item.toString(), Cart.class);
                String currentPrice = redisTemplate.opsForValue().get(PRICE_PREFIX+cart.getSkuId().toString());
                cart.setCurrentPrice(new BigDecimal(currentPrice));
                return cart;
            }).collect(Collectors.toList());
            return carts;
        }
        return null;
    }

    public void updateNum(Cart cart) {
        //更新redis缓存
        String userId = getUserId();
        BoundHashOperations<String, Object, Object> hashOps = redisTemplate.boundHashOps(userId);
        String skuId = cart.getSkuId().toString();
        BigDecimal count = cart.getCount();
        if (hashOps.hasKey(skuId)){
            Object cartJson = hashOps.get(skuId);
            cart = JSON.parseObject(cartJson.toString(), Cart.class);
            cart.setCount(cart.getCount().add(count));
            hashOps.put(skuId,JSON.toJSONString(cart));
        }
        //异步更新购物车
        cartServiceAsync.updateCountBySkuIdAndUserId(cart.getUserId(),cart.getSkuId(),cart);
    }

    /*
    根据用户id查询购物车中的商品信息
     */
    public List<Cart> queryCartByUserId(Long userId) {
        BoundHashOperations<String, Object, Object> boundHashOps = redisTemplate.boundHashOps(KEY_PREFIX+userId.toString());

        List<Object> values = boundHashOps.values();

        if (!CollectionUtils.isEmpty(values)){
            List<Cart> carts = values.stream().map(item -> JSON.parseObject(item.toString(), Cart.class)).collect(Collectors.toList());
            return carts;
        }

        return null;
    }
}
